package edu.berkeley.drivingbuddy;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;

import android.location.Criteria;
import android.app.Activity;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.AudioManager;
import android.media.SoundPool;
import android.media.SoundPool.OnLoadCompleteListener;
import android.os.Bundle;
import android.content.Intent;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.hardware.SensorEventListener;
import android.hardware.SensorEvent;
import android.hardware.SensorManager;
import android.hardware.Sensor;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Color;
import android.view.SurfaceView;
import android.util.Log;
import android.widget.Toast;

public class newCourseRunning extends MapActivity implements OnClickListener , SensorEventListener, DataPointTracker.DataPointListener, LocationListener {
    private MapView map;
    private MapController controller;
    private static LocationManager sLocationManager;
    private DataPointTracker dataTracker;
    
    private static final long LOCATION_UPDATE_MIN_DISTANCE =5;
    private static final long LOCATION_UPDATE_INTERVAL = 1000;
	private String LOCATION_PROVIDER;
    
	SensorManager mSensorManager;
    Sensor mAccelerometer;

    Button mButtonNewCourseStop;
    
    private SoundPool soundPool;
    private int badSoundId;
    private int goodSoundId;
    boolean loaded = false;
	boolean reported = false;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.newcourserunning);
	
		LOCATION_PROVIDER = ((LocationManager)getSystemService(LOCATION_SERVICE)).getBestProvider(new Criteria(), true);
		Log.d("db", LOCATION_PROVIDER);
        
        initMapView();
        initMyLocation();
        createRecord();
        
		mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
		mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mButtonNewCourseStop = (Button) findViewById(R.id.button_newcourserunning_stop);
        mButtonNewCourseStop.setOnClickListener(this);
        ((Button) findViewById(R.id.button_cancel)).setOnClickListener(this);
        
        this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
        // Load the sound
        soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);
        soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
            @Override
            public void onLoadComplete(SoundPool soundPool, int sampleId,
                    int status) {
                loaded = true;
            }
        });
        badSoundId = soundPool.load(this, R.raw.soundclip1, 1);
        goodSoundId = soundPool.load(this, R.raw.soundclipgood,1);
        
    }

    private void createRecord() {
        dataTracker = new DataPointTracker(this);
    }

    private void initMapView() {
        map = (MapView) findViewById(R.id.newcourserunning_map);
        controller = map.getController();
        map.setSatellite(false);
        map.setBuiltInZoomControls(true);
        
        final MyLocationOverlay overlay = new MyLocationOverlay(this, map);
        overlay.enableMyLocation();
        overlay.enableCompass();
        overlay.runOnFirstFix(new Runnable(){
            public void run(){
                controller.setZoom(15);
                controller.animateTo(overlay.getMyLocation());  
				registerLocation(overlay.getLastFix());
            }
        });

        map.getOverlays().add(overlay);     
    }

    private void initMyLocation() {
        sLocationManager =(LocationManager)getSystemService(LOCATION_SERVICE);
        sLocationManager.requestLocationUpdates(LOCATION_PROVIDER,
                LOCATION_UPDATE_INTERVAL, LOCATION_UPDATE_MIN_DISTANCE, this);
    }

    @Override
    protected void onResume() {
         super.onResume();
         mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
         sLocationManager.requestLocationUpdates(LOCATION_PROVIDER,
                 LOCATION_UPDATE_INTERVAL, LOCATION_UPDATE_MIN_DISTANCE, this);
    }

     @Override
    protected void onPause() {
         super.onPause();
         mSensorManager.unregisterListener(this);
         sLocationManager.removeUpdates(this);
     }
	
    @Override
    public void onClick (View v) {
		switch (v.getId()) {
			case R.id.button_cancel:
				DrivingBuddy.getMeOutOfHere();
				break;

			default:
				if (!reported) {
					Toast.makeText(this, "Please wait while we find your location...", Toast.LENGTH_LONG).show();
					return;
				}
				Location start = dataTracker.getStartLocation();
				Location end = dataTracker.getEndLocation();
				ResultGroup group = DrivingBuddy.getDatastore().queryForOrCreateResultGroup(start, end);
				ResultObj result = new ResultObj(group, group.getResults().size(), dataTracker.getScore(), dataTracker.getScoreHistory());
				group.addResult(result);
				DrivingBuddy.getDatastore().registerNewResult(result);
				startActivity(new Intent(this,newCourseDone.class).putExtra("id", result.getUniqueResultId()));
		}
    }
    
    @Override
    public void onSensorChanged(SensorEvent sensorEvent) {
        synchronized (this) {
            if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
				float ax = sensorEvent.values[0];
				float ay = sensorEvent.values[1];
				float az = sensorEvent.values[2];

				float accelMag = ax*ax + ay*ay + az*az;

				long time = System.currentTimeMillis();
				AccelerationDataPoint data = new AccelerationDataPoint(time, accelMag);
				dataTracker.addDataPoint(data);
            }
		}
    }

	@Override
    public void onAccuracyChanged(android.hardware.Sensor sensor,int accuracy) {
	}

    @Override
    protected boolean isRouteDisplayed() {
        // TODO Auto-generated method stub
        return false;
    }

	private void registerLocation(Location location) {
		reported = true;

		long time = System.currentTimeMillis();
        LocationDataPoint data = new LocationDataPoint(time, location);
        dataTracker.addDataPoint(data);
	}

    @Override
    public void onLocationChanged(Location location) {
		registerLocation(location);
    }

    @Override
    public void onProviderDisabled(String arg0) {
        // TODO Auto-generated method stub
    }

    @Override
    public void onProviderEnabled(String arg0) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
        // TODO Auto-generated method stub
    }

	@Override
	public void processRecentDrivingScore(float score) {
		Log.d("db", "recentDrivingScore: " + score);
		if (score > 0.8){
		    AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
		    float actualVolume = (float) audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
		    float maxVolume = (float) audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
		    float volume = actualVolume / maxVolume;
			// Is the sound loaded already?
            if (loaded) {
                soundPool.play(badSoundId, volume, volume, 1, 0, 1f);
                Log.e("Test", "Played sound");
            }
		}
	}
 
}
